/*
 * top.v
 * Top module for OrangeCrab board.
 *
 * Copyright 2024 dh33ex <dh33ex@riseup.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA or visit <http://www.gnu.org/licenses/>.
 *
 *
 */

`default_nettype none

`define EXT_FREQ 48000000
`define SOC_FREQ 1000000


module top (
    input clk48,
    input usr_btn,

    output rgb_led0_r,
    output rgb_led0_g,
    output rgb_led0_b,

    input  gpio_0,
    output gpio_1
);
    wire        rst;
    reg  [31:0] o_gpio;
    reg  [31:0] i_gpio;
    wire        clock_hw;

    soc soc(
        .i_clk(clock_hw),
        .i_rst(rst),
        .i_gpio(i_gpio),
        .o_gpio(o_gpio)
    );

    clk_div #(.DIVIDER(`EXT_FREQ/`SOC_FREQ)) clk_div_inst(
        .i_clk(clk48),
        .o_clk(clock_hw)
    );

    assign rst = ~usr_btn;
    assign {rgb_led0_g, rgb_led0_b, rgb_led0_r} = ~o_gpio[2:0];
    assign gpio_1 = clock_hw;
    assign i_gpio = {{31{0}}, gpio_0};

endmodule


module clk_div (
    input  i_clk,
    output o_clk
);
    parameter DIVIDER = 1;
    reg [$clog2(DIVIDER):0] counter = 0;

    reg buf_clk = 0;

    always @(posedge i_clk) begin
        counter <= counter + 1;
        if (counter == ((DIVIDER >> 1) - 1)) begin
            buf_clk <= ~buf_clk;
            counter <= 0;
        end
    end

    assign o_clk = buf_clk;
endmodule
